package controllers

import (
	"encoding/json"
	"github.com/astaxie/beego/logs"
	services "tinyrdm/backend/services"
	"tinyrdm/backend/types"
)

var logger = logs.GetLogger("Browser")

type BrowserController struct {
	BaseController
}

func NewBrowserController() *BrowserController {
	return &BrowserController{}
}

type BrowserReqData struct {
	Method     string             `json:"method"`
	Server     string             `json:"server"`
	Db         int                `json:"db"`
	Key        string             `json:"key"`
	NewKey     string             `json:"newKey"`
	Action     int                `json:"action"`
	FieldItems []any              `json:"fieldItems"`
	Items      []any              `json:"items"`
	Id         string             `json:"id"`
	Ids        []string           `json:"ids"`
	ValueStore map[string]float64 `json:"valueStore"`
	Keys       []any              `json:"keys"`
	Ttl        int64              `json:"ttl"`
	SerialNo   string             `json:"serialNo"`
	Name       string             `json:"name"`
	//	convert value
	Value  any    `json:"value"`
	Decode string `json:"decode"`
	Format string `json:"format"`
	Async  bool   `json:"async"`
	//	export keys
	Path          string `json:"path"`
	IncludeExpire bool   `json:"includeExpire"`

	PageNo   int `json:"pageNo"`
	PageSize int `json:"pageSize"`

	KeyDetailParam  types.KeyDetailParam  `json:"KeyDetailParam"`
	KeySummaryParam types.KeySummaryParam `json:"keySummaryParam"`
	Num             int64                 `json:"num"`

	Match      string `json:"match"`
	KeyType    string `json:"keyType"`
	ExactMatch bool   `json:"exactMatch"`

	HashValueParam types.SetHashParam `json:"hashValueParam"`
	SetKeyParam    types.SetKeyParam  `json:"SetKeyParam"`
	SetListParam   types.SetListParam `json:"setListParam"`
	SetSetParam    types.SetSetParam  `json:"setSetParam"`
	SetZSetParam   types.SetZSetParam `json:"setZSetParam"`

	Remove  bool  `json:"remove"`
	Members []any `json:"members"`
}

var browser = services.Browser()

func (c *BrowserController) Handler() {
	browser.Start(c.context())
	var req BrowserReqData
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
	if err != nil {
		logs.Error(err, string(c.Ctx.Input.RequestBody))
		c.ErrorJson(err)
		return
	}
	var resp any
	switch req.Method {
	case "Start":
		break
	case "OpenConnection":
		resp = browser.OpenConnection(req.Name)
		break
	case "OpenDatabase":
		resp = browser.OpenDatabase(req.Name, req.Db)
		break
	case "ServerInfo":
		resp = browser.ServerInfo(req.Name)
		break
	case "CleanCmdHistory":
		resp = browser.CleanCmdHistory()
		break
	case "CloseConnection":
		resp = browser.CloseConnection(req.Name)
		break
	case "Stop":
		browser.Stop()
		break
	case "AddHashField":
		resp = browser.AddHashField(req.Server, req.Db, req.Key, req.Action, req.FieldItems)
		break
	case "SetHashValue":
		resp = browser.SetHashValue(req.HashValueParam)
		break
	case "AddListItem":
		resp = browser.AddListItem(req.Server, req.Db, req.Key, req.Action, req.Items)
		break
	case "SetListItem":
		resp = browser.SetListItem(req.SetListParam)
		break
	case "AddStreamValue":
		resp = browser.AddStreamValue(req.Server, req.Db, req.Key, req.Id, req.FieldItems)
		break
	case "RemoveStreamValues":
		resp = browser.RemoveStreamValues(req.Server, req.Db, req.Key, req.Ids)
		break
	case "AddZSetValue":
		resp = browser.AddZSetValue(req.Server, req.Db, req.Key, req.Action, req.ValueStore)
		break
	case "UpdateZSetValue":
		resp = browser.UpdateZSetValue(req.SetZSetParam)
		break
	case "BatchSetTTL":
		resp = browser.BatchSetTTL(req.Server, req.Db, req.Keys, req.Ttl, req.SerialNo)
		break
	case "SetSetItem":
		resp = browser.SetSetItem(req.Server, req.Db, req.Key, req.Remove, req.Members)
		break
	case "UpdateSetItem":
		resp = browser.UpdateSetItem(req.SetSetParam)
		break
	case "ConvertValue":
		resp = browser.ConvertValue(req.Value, req.Decode, req.Format)
		break

	case "SetKeyTTL":
		resp = browser.SetKeyTTL(req.Server, req.Db, req.Key, req.Ttl)
		break
	case "DeleteKey":
		resp = browser.DeleteKey(req.Server, req.Db, req.Key, req.Async)
		break
	case "DeleteOneKey":
		resp = browser.DeleteOneKey(req.Server, req.Db, req.Key)
		break
	case "RenameKey":
		resp = browser.RenameKey(req.Server, req.Db, req.Key, req.NewKey)
		break

	case "DeleteKeys":
		resp = browser.DeleteKeys(req.Server, req.Db, req.Keys, req.SerialNo)
		break

	case "SetKeyValue":
		resp = browser.SetKeyValue(req.SetKeyParam)
		break
	case "GetKeyType":
		resp = browser.GetKeyType(req.KeySummaryParam)
		break
	case "GetKeySummary":
		resp = browser.GetKeySummary(req.KeySummaryParam)
		break
	case "ExportKey":
		resp = browser.ExportKey(req.Server, req.Db, req.Keys, req.Path, req.IncludeExpire)
		break

	case "GetClientList":
		resp = browser.GetClientList(req.Server)
		break
	case "GetCmdHistory":
		resp = browser.GetCmdHistory(req.PageNo, req.PageSize)
		break
	case "GetKeyDetail":
		resp = browser.GetKeyDetail(req.KeyDetailParam)
		break
	case "GetSlowLogs":
		resp = browser.GetSlowLogs(req.Server, req.Num)
		break
	case "FlushDB":
		resp = browser.FlushDB(req.Server, req.Db, req.Async)
		break
	case "ImportCSV":
		break
	case "LoadAllKeys":
		resp = browser.LoadAllKeys(req.Server, req.Db, req.Match, req.KeyType, req.ExactMatch)
		break
	case "LoadNextAllKeys":
		resp = browser.LoadNextAllKeys(req.Server, req.Db, req.Match, req.KeyType, req.ExactMatch)
		break
	case "LoadNextKeys":
		resp = browser.LoadNextKeys(req.Server, req.Db, req.Match, req.KeyType, req.ExactMatch)
		break
	default:
		resp = types.JSResp{
			Success: false,
			Msg:     "未找到该方法",
			Data:    nil,
		}
		logger.Printf("not found: %s", req.Method)
	}
	if resp == nil {
		resp = types.JSResp{
			Success: true,
			Msg:     "Successful",
			Data:    nil,
		}
	}
	c.postJson(resp)
}
